package cc.iits.demo.crane.api.bo;

import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 *
 */
public class Model extends Paging implements Serializable {

    private final static String METHOD_NAME_REPLACE="get";

    private final static String DESC = "desc";

    private List<Order> orders = null;

    public Model orderAsc(String field) {
        return order(field, Order.OrderBy.Asc);
    }
    public Model orderDesc(String field) {
        return order(field, Order.OrderBy.Desc);
    }

    /**
     * 排序
     *
     * @param field
     * @param orderBy
     * @return
     */
    public Model order(String field, Order.OrderBy orderBy) {
        initOrder();
        orders.add(new Order(field, orderBy));
        return this;
    }
    public <T> Model orderAsc(SFunction<T, ?> field) {
        return order(field, Order.OrderBy.Asc);
    }
    public <T> Model orderDesc(SFunction<T, ?> field) {
        return order(field, Order.OrderBy.Desc);
    }

    public List<Order> getOrder() {
        return orders;
    }

    public void setOrder(List<String> orders) {
        setOrderAsc(orders);
    }

    public void setOrderAsc(List<String> orders) {
        if (orders != null && orders.size() > 0) {
            for (String temp : orders) {
                if (StringUtils.isNotEmpty(temp)) {
                    orderAsc(temp.trim());
                }
            }
        }
    }

    public void setOrderDesc(List<String> orders){
        if (orders != null && orders.size() > 0) {
            for (String temp : orders) {
                if(StringUtils.isNotEmpty(temp)) {
                    orderDesc(temp.trim());
                }
            }
        }
    }


    private <T> Model order(SFunction<T, ?> field, Order.OrderBy orderBy) {
        initOrder();
        SerializedLambda m = LambdaUtils.resolve(field);
        String fieldName = m.getImplMethodName().replace(METHOD_NAME_REPLACE, StringUtils.EMPTY);
        Class clazz = m.getImplClass();
        Map<String, Field> fields = ReflectionKit.getFieldMap(clazz);
        for (String name : fields.keySet()) {
            if (fieldName.equalsIgnoreCase(name)) {
                orders.add(new Order(name, orderBy));
                break;
            }
        }
        return this;
    }
    private Model order(String field) {
        initOrder();
        orders.add(new Order(field));
        return this;
    }

    /**
     * 初始化
     */
    private void initOrder() {
        if (null == orders) {
            orders = new ArrayList<>();
        }
    }
}
